package controller

import (
	"time"

	. "gddgame.cc/galaxy/common/dsl/web"
	"gddgame.cc/galaxy/core/models"
	"gddgame.cc/galaxy/utils/def"
)

func GetFriendList(context def.Context, app *models.App, openId string, status bool, updateTime *time.Time) ([]models.UserOpen, error) {
	var friendList []models.UserFriend
	var userList []models.UserOpen
	userOpen, err := GetOpen(context, app, openId)
	if err != nil {
		return nil, err
	}
	query := models.UserFriendModel.Query()
	if status {
		query.Where("=", "app_id", app.Id).
			Where("=", "user_id", userOpen.UserId).
			Where("=", "status", models.ConfirmStatus)
	} else {
		query.Where("=", "app_id", app.Id).
			Where("=", "friend_id", userOpen.UserId).
			Where("=", "status", models.InvitedStatus)
	}
	if _, err := query.Find(&friendList); err != nil {
		return nil, SystemExceptionDetail("查找好友失败", err)
	}
	if len(friendList) == 0 {
		return nil, nil
	}
	ids := make([]int, len(friendList))
	for key := range friendList {
		if status {
			ids[key] = friendList[key].FriendId
		} else {
			ids[key] = friendList[key].UserId
		}
	}
	if _, err := models.UserOpenModel.Query().Where("=", "app_id", app.Id).Where("in", "user_id", ids).Find(&userList); err != nil {
		return nil, SystemExceptionDetail("查找好友失败", err)
	}
	return userList, nil
}

func IsFriend(context def.Context, app *models.App, openId string, friendOpenList []models.UserOpen) []bool {
	var friendList []models.UserFriend
	result := make([]bool, len(friendOpenList))
	userOpen, err := GetOpen(context, app, openId)
	if err != nil {
		return result
	}
	ids := make([]int, len(friendOpenList))
	idMap := make(map[int]int, len(friendOpenList))
	for key := range friendOpenList {
		ids[key] = friendOpenList[key].UserId
		idMap[friendOpenList[key].UserId] = key
	}
	query := models.UserFriendModel.Query()
	query.Where("=", "app_id", app.Id).
		Where("=", "user_id", userOpen.UserId).
		Where("=", "status", models.ConfirmStatus).
		Where("in", "friend_id", ids)
	if _, err := query.Find(&friendList); err != nil {
		return result
	}
	for _, value := range friendList {
		if key, ok := idMap[value.FriendId]; ok {
			result[key] = true
		}
	}
	return result
}

func InviteFriend(context def.Context, app *models.App, openId string, target string) error {
	var friend models.UserFriend
	var err error
	userOpen, err := GetOpen(context, app, openId)
	if err != nil {
		return err
	}
	targetOpen, err := GetOpen(context, app, target)
	if err != nil {
		return err
	}
	if ok, _ := models.UserFriendModel.Query().
		Where("=", "app_id", app.Id).
		Where("=", "user_id", userOpen.UserId).
		Where("=", "friend_id", targetOpen.UserId).One(&friend); ok {
		return nil
	}
	if _, err := models.UserFriendModel.Insert(&models.UserFriend{
		UserId:   userOpen.UserId,
		AppId:    app.Id,
		FriendId: targetOpen.UserId,
		Status:   models.InvitedStatus,
	}); err != nil {
		return SystemExceptionDetail("邀请好友失败", err)
	}

	return nil
}

func ConfirmFriend(context def.Context, app *models.App, openId string, target string, confirm bool) error {
	var friend models.UserFriend
	var friendT models.UserFriend
	var err error
	var ok bool
	userOpen, err := GetOpen(context, app, openId)
	if err != nil {
		return err
	}
	targetOpen, err := GetOpen(context, app, target)
	if err != nil {
		return err
	}
	if ok, err := models.UserFriendModel.Query().
		Where("=", "app_id", app.Id).
		Where("=", "user_id", targetOpen.UserId).
		Where("=", "friend_id", userOpen.UserId).One(&friend); !ok {
		return ValidExceptionDetail("NO_INVITED_FRIEND", err)
	}
	if friend.Status != models.InvitedStatus {
		return nil
	}
	sx, err := models.UserFriendModel.Begin()
	if err != nil {
		return SystemExceptionDetail("确认好友失败", err)
	}
	if confirm {
		if ok, _ = models.UserFriendModel.Query().Session(sx).
			Where("=", "app_id", app.Id).
			Where("=", "user_id", userOpen.UserId).
			Where("=", "friend_id", targetOpen.UserId).One(&friendT); !ok {
			if _, err = models.UserFriendModel.Session(sx).Save(true, &models.UserFriend{
				UserId:   userOpen.UserId,
				AppId:    app.Id,
				FriendId: targetOpen.UserId,
				Status:   models.ConfirmStatus,
			}); err != nil {
				goto Rollback
			}
		} else {
			if _, err = models.UserFriendModel.PK(friendT.Id).Session(sx).Update(map[string]interface{}{
				"status": models.ConfirmStatus,
			}); err != nil {
				goto Rollback
			}
		}
		if _, err = models.UserFriendModel.PK(friend.Id).Session(sx).Update(map[string]interface{}{
			"status": models.ConfirmStatus,
		}); err != nil {
			goto Rollback
		}
	} else {
		if _, err = models.UserFriendModel.PK(friend.Id).Session(sx).Delete(); err != nil {
			goto Rollback
		}
	}

	if err = sx.Commit(); err != nil {
		goto Rollback
	}
	return nil
Rollback:
	_ = sx.Rollback()
	return SystemExceptionDetail("确认好友失败", err)
}
